package org.dawfinn.droiditarian.server;

import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

public class ReverseGeocoder {
	
	private static final String MAPS_API_KEY="ABQIAAAADSU-Hs9vhhGaSKZmyXaJKhQLMYoEiuNoIqM2obWFPNfePzLqEhS8jxtrd7aLFxeyt_8t39QOdbQojg";
	private static final String GEOCODE_REQUEST_PREFIX = "http://maps.google.com/maps/api/geocode/xml";
	private static final String LATLNG_PARAM = "latlng";
	private static final String KEY_PARAM = "key";
	private static final String SENSOR_PARAM = "sensor";
	private static final String LOCALITY_XPATH_EXPRESSION = "//result[1]//address_component[type/text() = 'locality']/long_name/text()";
	private static final String COUNTRY_XPATH_EXPRESSION = "//result[1]//address_component[type/text() = 'country']/long_name/text()";
	private static final String ADMIN_AREA_XPATH_EXPRESSION = "//result[1]//address_component[type/text() = 'administrative_area_level_1']/short_name/text()";
	
	public Location getLocation(float lat, float lng) {
		try {
			URL url = new URL(GEOCODE_REQUEST_PREFIX + "?" + LATLNG_PARAM + "=" + lat + "," + lng + "&" + SENSOR_PARAM + "=false&" + KEY_PARAM + "=" +MAPS_API_KEY);
			Document resultDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url.openStream());
			String locality = null, country = null, adminArea = null;
			XPath xPath = XPathFactory.newInstance().newXPath();
			locality = (String) xPath.evaluate(LOCALITY_XPATH_EXPRESSION, resultDocument, XPathConstants.STRING);
			country = (String) xPath.evaluate(COUNTRY_XPATH_EXPRESSION, resultDocument, XPathConstants.STRING);
			adminArea = (String) xPath.evaluate(ADMIN_AREA_XPATH_EXPRESSION, resultDocument, XPathConstants.STRING);
			return new Location(locality, adminArea, country);
		} catch (Exception e) {
			Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Reverse geocode requeset failed", e);
		}
		return null;
	}

}
